;
;		TERM.A86
;
;Terminal routines with text file I/O for MODEM9.xx.
;
DSKSAVE:
	CALL	CKMODM
	MOV	AL,BYTE PTR .FCB+1	;FIRST CHAR OF FILENAME
	CMP	AL,' '		;FILE SPEC'D
	JNZ	GOODNM		;YES, GOOD NAME
	MOV	NFILFLG,TRUE
	MOV	SAVEFLG,FALSE
	JMP	TERM
;
GOODNM:
	CALL	ERASFIL
	CALL	MOVE2
	MOV	DX,OFFSET FCB3
	MOV	CL,MAKE
	INT	224
	MOV	DX,OFFSET FCB3
	MOV	CL,OPEN
	INT	224
	MOV	BX,OFFSET BOTTRAM
	MOV	HLSAVE,BX
	MOV	NFILFLG,0
	MOV	LISTMOR,0	;STOP ANY BUFFERED PRINTER OUTPUT
TERM:
	TEST	LISTMOR,0FFH	;ANY BUFFERED PRINTER OUTPUT?
	JZ	TERM1
	CALL	GOLIST		;GO IF SO
TERM1:
	CALL	STAT		;KEYPRESS?
	JNZ	TERM2
	JMP	TERML		;NO, CHECK LINE

TERM2:
	CALL	KEYIN		;GET CHAR FROM KBD
	CMP	AL,' '
	JC	TERM3
	JMP	NOTOG		;GO IF NOT CONTROL CHARACTER

TERM3:
	MOV	CH,AL		;SAVE
	CMP	AL,BKSP		;TEST FOR BACKSPACE
	JNZ	NOBKSP
	TEST	CONVBKSP,0FFH	;CONVERT BACKSPACE TO RUB?
	JZ	NOBKSP		;GO IF NO CONVERSION
	MOV	AL,RUB
	JMP	NOTOG

NOBKSP:
	TEST	EXACFLG,0FFH	; EXACT ?
	MOV	EXACFLG,0	;CLR FOR NEXT TIME
	JZ	NOTEXAFLG	;GO OF EXAFLG FALSE
	TEST	LOCONEXTCHR,0FFH	;SHOULD WE SEND ON EXAFLG?
	MOV	AL,CH
	JNZ	NOBKSP1
	JMP	NOTOG		;YES, IF LOCONEXTCHR FALSE

NOBKSP1:
	MOV	AL,EXTCHR	;WE WANT TO SEND EXTCHR IN ANY CASE
	CMP	AL,CH
	MOV	AL,CH
	JNZ	NOBKSP2
	JMP	NOTOG		;SEND IF EXTCHR

NOBKSP2:
	JMP	LOCCHK		;OTHERWISE DO LOCAL STUFF

NOTEXAFLG:
	MOV	AL,EXTCHR	;TREAT NEXT CHARACTER IN SPECIAL WAY?
	CMP	AL,CH
	JNZ	NOTEXA1
	JMP	EXTFLG		;YES, SET EXAFLG FOR NEXT CHAR

NOTEXA1:
	MOV	AL,LOCONEXTCHR
	OR	AL,AL		;SHOULD WE SEND IF NOT EXAFLG
	MOV	AL,CH
	JZ	LOCCHK
	JMP	NOTOG		;YES, IF LOCONEXTCHR TRUE

LOCCHK:
	MOV	AL,EXITCHR	;RETURN TO MENU?
	CMP	AL,CH
	JNZ	LOCCHK1
	JMP	EXITMEN		;YES, RETURN TO MENU

LOCCHK1:
	MOV	AL,TRANCHR	;OUTPUT TEXT FILE TO REMOTE?
	CMP	AL,CH
	JNZ	LOCCHK2
	CALL	TRANSFER	;SEND-A-FILE (BLIND SEND)
LOCCHK2:
	JNZ	LOCCHK3
	JMP	TERM		;LOOP

LOCCHK3:
	MOV	AL,TRANLOGON
	OR	AL,AL
	JZ	SKPLOGON
	MOV	AL,LOGCHR	;SEND LOGON?
	CMP	AL,CH
	JNZ	SKPLOGON
	JMP	SENDLOG

SKPLOGON:
	MOV	AL,LSTTST
	OR	AL,AL
	JZ	NOLST
	MOV	AL,LSTCHR
	CMP	AL,CH
	JNZ	NOLST
	MOV	AL,LISTFLG
	NOT	AL
	MOV	LISTFLG,AL
	CALL	CRLF
	CALL	CRLF
	CALL	LSTMSG
	CALL	CRLF
	JMP	TERML

NOLST:
	MOV	AL,UNSAVECHR	;CLOSE INPUT BUFFER?
	CMP	AL,CH
	JZ	S2A		;IF YES, DISABLE COPY
	MOV	AL,SAVECHR	;OPEN INPUT BUFFER?
	CMP	AL,CH
	MOV	AL,CH		;RESTORE CHARACTER TYPED
	JZ	NOLST1
	JMP	NOTOG

NOLST1:
	MOV	AL,NFILFLG	;DO NOT ALLOW SAVE IF..
	CMP	AL,TRUE		;..THIS FLAG IS SET.
	JNZ 	NOLST1A
	JMP	TERML

NOLST1A:
	MOV	AL,TRUE		;0FFH -- ALLOW COPY INTO FILE
	JMP	S2B

S2A:
	MOV	AL,FALSE	;0 -- STOP COPY INTO FILE
S2B:
	MOV	SAVEFLG,AL
	CALL	BUFMSG
	JMP	TERML
;
BUFMSG:
	CALL	ILPRT
	DB	CR,LF,LF,'** Memory buffer ',0
	TEST	SAVEFLG,0FFH
	JZ	BUFMSG2
	CALL	ILPRT
	DB	'open **',CR,LF,LF,':',BELL,0
	RET
;
BUFMSG2:
	CALL	ILPRT
	DB	'closed **',CR,LF,LF,BELL,0
	RET
;
EXITMEN:
	CALL	CRLF
	CALL	CLREOS		;CLEAR TO END OF SCREEN TO CLEAN UP ANY MESS
	JMP	MENU0
;
SENDREADY:
	CALL	INMODCTLP
	CALL	ANIMODSNDB
	CALL	CPIMODSNDR
	RET
;
SENDLF:
	CALL	SENDREADY
	JNZ	NOLFYET		;GO IF NOT READY FOR OUTPUT YET
	MOV	AL,LF
	JMP	NOTOG		;SEND LF

NOLFYET:
	CALL	EXITTEST
	JNC	EXITMEN		;GO IF SO, SO DON'T GET HUNG UP
	JMP	SENDLF		;ELSE KEEP TRYING TO SEND LF
;
SENDLOG:
	PUSH	BX
SNDLG2:
	CALL	STAT
	JZ	SNDLG2
	CALL	KEYIN
	CALL	UCASE
	CMP	AL,'L'		;TEST IF LIST OF STRINGS REQUESTED
	JZ	GIVESTRS
	SUB	AL,'0'
	CMP	AL,10
	JNC	ENDLOG
	ADD	AL,AL		;X2
	ADD	AL,AL		;X4
	ADD	AL,AL		;X8
	ADD	AL,AL		;X16
	MOV	DL,AL
	MOV	DH,0
	PUSH	DX
	POP	BX
	ADD	BX,DX		;X32 IN HL
	MOV	DX,OFFSET STRINGS	;DE POINTS TO START OF STRINGS
	ADD	BX,DX
LOGLP:
	CALL	SENDREADY
	JNZ	NOSENDLOG	;GO IF NOT READY
	MOV	AL,BYTE PTR [BX]	;GET LOGON BYTE
	INC	BX
	CMP	AL,0		;IS IT THE END?
	JZ	ENDLOG		;GO IF SO
	CALL	OUTMODDATP
	JMP	LOGLP

NOSENDLOG:
	CALL	EXITTEST	;TEST SO DON'T GET HUNG UP
	JNC	EXITLOG		;GO IF OPERATOR WANTS EXIT
	JMP	LOGLP
;
ENDLOG:
	POP	BX
	JMP	TERML
;
EXITLOG:
	POP	BX
	JMP	EXITMEN
;
EXITTEST:
	CALL	STAT		;KEYPRESS?
	JZ	NOKEY
	CALL	KEYIN	
	MOV	CH,AL
	MOV	AL,EXITCHR	;SEE IF OPERATOR WANTS EXIT
	CMP	AL,CH
	JNZ	NOKEY		;GO IF WRONG KEY		
	STC
	CMC			;RESET FOR EXIT
	RET

NOKEY:
	STC			;SET FOR NO KEY OR WRONG KEY
	RET
;
GIVESTRS:
	CALL	ILPRT
	DB	CR,LF,'    List of Strings',CR,LF,LF,LF,0
	MOV	BX,OFFSET STRINGS
	MOV	STRSAVE,BX
	MOV	CH,'0'
GVSTRS1:
	MOV	AL,CH
	CALL	TIPE
	CALL	ILPRT
	DB	'  =  ',0
	MOV	BX,STRSAVE
	MOV	AL,BYTE PTR [BX]
	CMP	AL,0
	JNZ	NONULL
	CALL	ILPRT
	DB	'* null string *',0
	JMP	GVSTRS2

NONULL:
	MOV	BX,STRSAVE
NONUL2:
	MOV	AL,BYTE PTR [BX]
	CMP	AL,0
	JZ	GVSTRS2
	CMP	AL,CR
	JZ	NONUL3
	CALL	TIPE
NONUL3:
	JNZ	NOTACR
	PUSH	BX
	CALL	ILPRT
	DB	'<CR>',0
	POP	BX
NOTACR:
	INC	BX
	JMP	NONUL2
;
GVSTRS2:
	MOV	AL,'9'
	CMP	AL,CH
	JZ	GVSTRS3
	INC	CH
	MOV	BX,STRSAVE
	MOV	DX,OFFSET 32
	ADD	BX,DX
	MOV	STRSAVE,BX
	CALL	CRLF
	JMP	GVSTRS1
;
GVSTRS3:
	CALL	ILPRT
	DB	CR,LF,LF,'Enter number to transmit string',CR,LF,0
	POP	BX
	JMP	SENDLOG
;
EXTFLG:
	MOV	AL,TRUE
	MOV	EXACFLG,AL
	JMP	TERML
;
RCVREADY:
	CALL	INMODCTLP
	CALL	ANIMODRCVB
	CALL	CPIMODRCVR
	RET
;
LSTMSG:
	MOV	AL,LISTFLG
	OR	AL,AL
	JZ	LSTMSG2
	CALL	ILPRT
	DB	'Printer is on',CR,LF,0
	RET

LSTMSG2:
	CALL	ILPRT
	DB	'Printer is off',CR,LF,0
	RET
;
NOTOG:
	PUSH	AX
NOTOG1:
	CALL	SENDREADY
	JNZ	NOTOG1
	POP	AX
	CALL	OUTMODDATP
	MOV	CH,AL
	MOV	AL,LOCFLG
	OR	AL,AL
	JNZ	LTYPE
	MOV	AL,ECHOFLG
	OR	AL,AL
	JZ	CHKCR
LTYPE:
	MOV	AL,CH
	CALL	TIPE
	CALL	CHKSAVE		;TO STORE LOCAL IF BUFFER OPEN
	CALL	CHKPRNT
CHKCR:
	MOV	AL,CR
	CMP	AL,CH
	JNZ	TERML
	MOV	AL,ADDLF
	OR	AL,AL
	JZ	TERML
	JMP	SENDLF
;
TERML:
	CALL	RCVREADY	;TEST FOR RECEIVED CHARACTER
	JZ	TERML1
	JMP	TERM

TERML1:
	CALL	INMODDATP
	AND	AL,7FH		;STRIP PARITY
	JNZ	GIVLF
	JMP	TERM	

GIVLF:
	MOV	CH,AL
	CALL	TIPE
	CALL	CHKSAVE
	CALL	CHKPRNT
	MOV	AL,ECHOFLG
	OR	AL,AL
	JZ	NOECHO
	MOV	AL,CH
	CALL	OUTMODDATP
NOECHO:
	MOV	AL,CR
	CMP	AL,CH
	JZ	NOECHO1
	JMP	TERM

NOECHO1:
	MOV	AL,ADDLF
	JNZ	NOECHO2
	JMP	TERM

NOECHO2:
	MOV	AL,ECHOFLG
	OR	AL,AL
	JZ	NOECHO3
	JMP	SENDLF

NOECHO3:
	MOV	AL,LF
	JMP	GIVLF
;
CHKSAVE:
	MOV	AL,SAVEFLG
	OR	AL,AL
	JNZ	CHKSAVE1
	RET

CHKSAVE1:
	MOV	BYTE PTR [BX],CH
	INC	BX
	MOV	HLSAVE,BX	;MENU COMMAND DESTROYS HL-REG..
	MOV	AL,LF
	CMP	AL,CH
	JNZ	NOCOLON		;..TYPE ":" AFTER EACH LINE FEED..
	MOV	AL,':'		;..WHEN MEMORY SAVE ACTIVE.
	CALL	TIPE
NOCOLON:
	CALL	GETMAX
	CMP	AL,BH
	PUSH	CX
	JNZ	NOCOLON1
	CALL	INTDSKSV
NOCOLON1:
	POP	CX
	RET
;
GETMAX:
	MOV	AL,XAST SHR 8	;END OF RESERVED BUFFER HAS BEEN
	RET			;..REACHED AND DISKSAVE IS NEEDED.
;
CHKPRNT:
	TEST	LISTFLG,0FFH	;OUT TO PRINTER?
	JNZ	CHKPRNT1
	RET			;RETURN IF NOT

CHKPRNT1:
	TEST	NFILFLG,0FFH	;IS BUFFER USED FOR FILE?
	JZ	NOBUFF		;DON'T BUFFER PRINTER IF SO, HOWEVER CHARACTERS
				;WILL BE LOST IF PRINTER IS SLOWER THAN MODEM
	CALL	GETMAX		;GET MAXIMUM FOR BUFFER
	MOV	BX,HLSAVE1	
	CMP	AL,BH		;ARE WE THERE?
	JNZ	NOTMAX		;GO IF NOT
	MOV	BX,OFFSET BOTTRAM	;FLUSH BUFFER
	MOV	HLSAVE1,BX
	MOV	HLSAVE2,BX
NOTMAX:	
	MOV	BYTE PTR [BX],CH	;SAVE CHARACTER IN BUFFER
	INC	BX		;INCREMENT END OF BUFFER
	MOV	HLSAVE1,BX
	MOV	AL,TRUE		;SET FLAG FOR PRINTER OUTPUT
	MOV	LISTMOR,AL
	RET
;
NOBUFF:
	CALL	LSTSTAT	
	JNZ	NOBUFF1
	RET			;RETURN IF PRINTER BUSY

NOBUFF1:
	MOV	CL,CH		;ELSE PRINT CHARACTER
	CALL	LISTER
	RET
;
GOLIST:
	CALL	LSTSTAT
	JNZ	GOLIST1
	RET			;RETURN IF PRINTER BUSY

GOLIST1:
	MOV	BX,HLSAVE2	;GET LOCATION OF NEXT CHARACTER TO PRINT
	MOV	CL,BYTE PTR [BX]	;GET CHARACTER
	INC	BX		;INCREMENT POINTER
	MOV	HLSAVE2,BX
	CALL	CMPBUFF		;CHECK FOR END OF BUFFER
	CALL	LISTER		;PRINT
	RET
;
;ROUTINE CHECKS FOR END OF BUFFER, RESETS BUFFER IF SO AND STOPS
;PRINTER OUTPUT
;
CMPBUFF:
	MOV	BX,HLSAVE2
	CMP	BX,HLSAVE1
	JZ	CMPBUFF1
	RET

CMPBUFF1:
	MOV	BX,OFFSET BOTTRAM
	MOV	HLSAVE1,BX
	MOV	HLSAVE2,BX
	MOV	LISTMOR,0
	RET
;
INTDSKSV:
	MOV	AL,XOFF		;SEND A CTRL-S TO STOP..
	CALL	OUTMODDATP  	;..REMOTE COMPUTER OUTPUT.
	MOV	DH,0         	;D IS THE BUFFER COUNT
	CALL	INMODEM		;GET LAST BYTES SENT..
	MOV	LASTBYT1,AL	;..AFTER CTRL-S.
	CALL	INMODEM		;ADD MORE CALLS TO INMODEM..
	MOV	LASTBYT2,AL	;..AND STA LASTBYT# IF YOU ARE..
	PUSH	DX
	CALL	NUMREC1
	CALL	WRTDSK		;WRITE THE RECORDS
	POP	DX
	MOV	BX,OFFSET BOTTRAM
	INC	DH
	DEC	DH		;TEST BUFFER COUNT FOR ZERO
	JZ	CTRLQ
	MOV	AL,LASTBYT1	;GET THE LAST BYTES THAT WERE..
	MOV	BYTE PTR [BX],AL	;..SAVED AND PUT THEM IN..
	INC	BX		;..BOTTRAM.
	CALL	TIPE
	DEC	DH
	JZ	CTRLQ
	MOV	AL,LASTBYT2
	MOV	BYTE PTR [BX],AL
	INC	BX
	CALL	TIPE
CTRLQ:
	MOV	AL,XON		;SEND START CHARACTER..
	CALL	OUTMODDATP	;..TO REMOTE COMPUTER.
	RET
;
;THIS SUBROUTINE WILL LOOP UNTIL THE MODEM RECEIVES A CHARACTER
;OR 100 MILLISECONDS. IF A CHARACTER IS RECEIVED, A FLAG IS SET
;TO STORE THE CHARACTER. A MAXIMUM OF TWO CHARACTERS ARE STORED,
;BUT MORE MAY BE STORED IF DESIRED (SEE COMMENT IN "INTDSKSV"
;ABOVE).
;
INMODEM:
	PUSH	BX
	MOV	BX,OFFSET 625
	CALL	FIXCNT
	PUSH	BX
	POP	CX
	POP	BX
TIMERL:
	CALL	RCVREADY
	JZ	GETBYTE
	DEC	CX
	MOV	AL,CH
	OR	AL,CL
	JNZ	TIMERL
	RET
;
GETBYTE:
	CALL	INMODDATP
	INC	DH
	RET
;
NUMRECS:
	MOV	BYTE PTR [BX],EOFCHAR
	INC	BX
	MOV	DX,OFFSET 127
	ADD	BX,DX
NUMREC1:
	MOV	DX,-(OFFSET BOTTRAM)
	ADD	BX,DX
	MOV	AL,BL		;DIVIDE HL BY 128..
	RCL	AL,1		;High bit set if sector to save
	MOV	AL,0		;Save in carry
	RCL     AL,1		;Now see if needed
	MOV	BL,BH		;..NUMBER OF SECTORS
	MOV	BH,0
	PUSH	AX
	ADD	BX,BX
	POP	AX
	ADC	AL,BL
	MOV	BL,AL		;RETURNS WITH NUMBER OF..
	RET			;..128 BYTE RECORDS IN HL.
;
WRTDSK:
	MOV	DX,OFFSET BOTTRAM
NEXTWRT:
	MOV	CL,STDMA
	CALL	BDOSRT
	PUSH	DX
	MOV	DX,OFFSET FCB3
	MOV	CL,WRITE
	CALL	BDOSRT
	POP	DX
	ADD	DX,128
	DEC	BX
	JNZ	NEXTWRT
	RET
;
CLOSE3:
	MOV	DX,OFFSET FCB3
	MOV	CL,CLOSE
	INT	224
	RET
;
BDOSRT:
	PUSH	CX
	PUSH	DX
	PUSH	BX
	PUSH	AX
	INT	224
	POP	AX
	POP	BX
	POP	DX
	POP	CX
	RET
;
MOVE2:
	MOV	BX,OFFSET FCB3
	CALL	INITFCBS
	MOV	BX,OFFSET FCB
	MOV	DX,OFFSET FCB3
	MOV	CH,12
	CALL	MOVE
	RET
;
;FILE TRANSFER ROUTINE - CALLED WITH 
;CONTROL-T FROM TERMINAL ROUTINE.
;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X.
;
TRANSFER:
	PUSH	BX
	PUSH	DX
	PUSH	CX
	PUSH	AX
	MOV	BX,OFFSET FCB4
	CALL	INITFCBS 	;INITIALIZES FCBS POINTED..
	MOV	BX,OFFSET FCB+16 ;..TO BY HL REG.
	CALL	INITFCBS
GET:
	CALL	GETNAME
	MOV	AL,CMDBUF+2 	;WAS FILE ENTERED
	CMP	AL,20H
	JZ	TRANSL2
	CALL	MOVE4
	CALL	OPEN4
	CMP	AL,0FFH		;RETURN WITH 0FFH MEANS
	JNZ	CONTIN		;FILE DOES NOT EXIST
TRANSL1:
	CALL	ILPRT
	DB	CR,LF,'++ File does not exist ++',CR,LF,0
TRANSL2:
	CALL	ILPRT
	DB	'Type "R" to return to modem',CR,LF
	DB	'Type "A" to re-enter name: ',BELL,0
	CALL	KEYIN
	CALL	UCASE
	PUSH	AX
	CALL	TIPE		;ECHO RESPONSE
	CALL	CRLF
	POP	AX
	CMP	AL,'A'
	JNZ	TRANSL3
	JMP	GET

TRANSL3:
	CMP	AL,'R'
	JNZ	TRANSL2
	JMP	RETURN
;
CONTIN:
	MOV	DX,OFFSET 80H
	MOV	CL,STDMA
	INT	224
READMR:
	CALL	READ80
	CMP	AL,1		;END OF FILE
	JZ	RETURNS
	CMP	AL,2		;BAD READ
	JZ	RETURNU
	CALL	SEND80C
	CMP	AL,EOFCHAR	;END OF FILE - OMIT IF OBJECT..
	JZ	RETURNS		;..CODE IS TO BE SENT.
	CMP	AL,CAN		;CANCELLATION?
	JZ	TRANCAN
	JMP	READMR
;
RETURNS:
	CALL	ILPRT
	DB	CR,LF,'File transfer completed',CR,LF,BELL,0
	JMP	RETURN
;
RETURNU:
	CALL	ILPRT
	DB	CR,LF,'++ File transfer unsuccessful ++',CR,LF,BELL,0
	JMP	RETURN
;
TRANCAN:
	CALL	ILPRT
	DB	CR,LF,LF,'++ Transfer cancelled ++',CR,LF,BELL,0
RETURN:
	POP	AX
	POP	CX
	POP	DX
	POP	BX
	RET
;
INITFCBS:			;ENTRY AT +2 WILL LEAVE..
	MOV	BYTE PTR [BX],0	;..DRIVE NO. INTACT.
	INC	BX		;WILL INITIALIZE AN FCB..
	MOV	CH,11		;..POINTED TO BY HL-REG. FILLS 1ST POS
LOOP10:
	MOV	BYTE PTR [BX],' '	;..WITH 0, NEXT 11 WITH..
	INC	BX		;..WITH BLANKS, AND LAST..
	DEC	CH		;..21 WITH NULLS.
	JNZ	LOOP10
	MOV	CH,21
LOOP11:
	MOV	BYTE PTR [BX],0
	INC	BX
	DEC	CH
	JNZ	LOOP11
	RET
;
GETNAME:
	CALL	ILPRT
	DB	CR,LF,'Enter file name to be transferred -  <CR> TO QUIT: ',0
	MOV	DX,OFFSET CMDBUF
	CALL	INBUFF
	CALL	CRLF
	RET
;
MOVE4:
	MOV	DX,OFFSET CMDBUF
	MOV	BX,OFFSET FCB4
	CALL	CPMLINE
	RET
;
OPEN4:
	MOV	DX,OFFSET FCB4
	MOV	CL,OPEN
	INT	224
	RET
;
READ80:
	MOV	DX,OFFSET FCB4
	MOV	CL,READ
	INT	224
	RET
;
SEND80C:
	MOV	CH,80H
	MOV	BX,OFFSET 80H
SENDCH1:
	PUSH	DX
	CALL	SPEED
	POP	DX
	MOV	AL,BYTE PTR [BX]
	CMP	AL,EOFCHAR
	JNZ	SENDCH3
	MOV	AL,EOFSEND
	OR	AL,AL
	JNZ	SENDCH2
	RET

SENDCH2:
	MOV	AL,BYTE PTR [BX]
SENDCH3:
	CALL	MODOUT
	CMP	AL,EOFCHAR
	JNZ	SENDCH4
	RET

SENDCH4:
	CALL	STAT		;TEST TO SEE IF
	OR	AL,AL		;CANCELLATION REQUESTED
	JZ	SKIP12
	CALL	KEYIN
	CMP	AL,CAN
	JNZ	SKIP12
	RET

SKIP12:
	INC	BX
	DEC	CH
	JNZ	SENDCH1
	RET
;
MODOUT:
	PUSH	AX
MODOUTL:
	MOV	AL,XOFFTST
	OR	AL,AL
	JZ	MODOUTL1
	CALL	TXOFF
MODOUTL1:
	CALL	SENDREADY
	JNZ	MODOUTL
	MOV	AL,STRLF
	OR	AL,AL
	JZ	NOLFTST
	POP	AX
	PUSH	AX
	CMP	AL,LF
	JZ	NOTMOUT
NOLFTST:
	POP	AX
	PUSH	AX
	MOV	SAVEOUT,AL	;SAVE OUTPUT FOR POSSIBLE ECHO TEST
	CALL	OUTMODDATP
	MOV	AL,ECHWAIT	;DO WE WANT TO TEST FOR ECHOED CHAR?
	OR	AL,AL
	JZ	NOTMOUT
	CALL	WAITECHO	;GO IF SO
NOTMOUT:
	POP	AX
	CALL	TIPE
	CMP	AL,CR
	JZ	DLYCR
	RET
;
DLYCR:
	MOV	AL,XONWAIT	;WAIT FOR XON AFTER CR?
	OR	AL,AL
	JNZ	WAITXON
	MOV	AL,CRDLY	;EXTRA DELAY AFTER CR
	JMP	DLYCR2
;
SPEED:
	MOV	AL,BYTDLY	;GET SPEED VALUE (0-9)
				;DELAY IS FROM 0.02 SEC FOR SPDVAL = 1
				;TO 0.18 SEC FOR SPDVAL	= 9
DLYCR2:
	OR	AL,AL
	JNZ	DLYCR3
	RET			;RETURN IF 0

DLYCR3:
	MOV	CL,AL
SPDLP:
	CALL	SPD1		;OUTER LOOP
	DEC	CL
	JNZ	SPDLP
	RET
;
SPD1:
	PUSH	BX
	MOV	BX,OFFSET 357	;ABOUT 0.02 SEC
	MOV	AL,XOFFTST
	OR	AL,AL
	JZ	SPD2
	MOV	BX,OFFSET 102	;ADJUST FOR XOFF TESTING
	MOV	AL,ECHOFLG
	OR	AL,AL
	JZ	SPD2
	MOV	AL,LOCFLG
	OR	AL,AL
	JZ	SPD2
	MOV	BX,OFFSET 76	;ADJUST AGAIN FOR REMOTE ECHO
SPD2:
	CALL	FIXCNT
	PUSH	BX
	POP	DX
	POP	BX
SPDLP1:
	DEC	DX	;INNER LOOP
	MOV	AL,XOFFTST
	OR	AL,AL
	JZ	SPDLP2
	CALL	TXOFF
SPDLP2:
	MOV	AL,DL
	OR	AL,DH
	JNZ	SPDLP1
	RET
;
TXOFF:
	CALL	RCVREADY
	JZ	TXOFF1
	RET

TXOFF1:
	CALL	INMODDATP
	AND	AL,7FH
	CMP	AL,XOFF
	JNZ	TXOFF2
	CALL	WAITXON
TXOFF2:
	RET
;
WAITXON:
	CALL	RCVREADY
	JNZ	WTXON2
	CALL	INMODDATP
	AND	AL,7FH
	CMP	AL,XON
	JNZ	WTXON2
	RET

WTXON2:
	CALL	STAT		;TEST TO SEE IF
	OR	AL,AL		;CANCELLATION REQUESTED
	JZ	WAITXON		;SO DON'T GET HUNG UP
	CALL	KEYIN
	CMP	AL,CAN
	JNZ	WAITXON
 	RET
;
WAITECHO:
	MOV	AL,50		;1 SECOND MAXIMUM DELAY WAITING FOR ECHO
	MOV	MECHDLY,AL
WTECH1:
	CALL	RCVREADY	;IS THERE INPUT?
	JNZ	WTECH2		;GO IF NOT
	CALL	INMODDATP	;GET INPUT
	AND	AL,7FH
	MOV	CL,AL		;SAVE INPUT
	MOV	AL,SAVEOUT	;GET OUTPUT
	CMP	AL,CL		;ARE THEY THE SAME?
	JNZ	WTECH1A
	RET			;RETURN IF SO

WTECH1A:
	MOV	AL,SAVEOUT	;GET OUTPUT
	CMP	AL,TAB		;CHECK IF TAB
	JNZ	WTECH2		;GO IF NOT
	MOV	AL,SPACE	;MAYBE REMOTE CONVERTS TABS TO SPACES
	CMP	AL,CL		
	JNZ	WTECH2
	RET			;RETURN IF SPACE ECHOED ON TAB OUTPUT

WTECH2:
	MOV	AL,MECHDLY	;LOOP FOR 1 SECOND
	DEC	AL
	MOV	MECHDLY,AL
	JNZ	WTECH3
	RET

WTECH3:
	MOV	AL,1		;0.02 SECOND
	CALL	DLYCR2
	JMP	WTECH1
;	
; Check for any garbage characters on line.
;
CKMODM:
	CALL	RCVREADY	;ANY CHARACTERS READY TO RECEIVE?
	JZ	CKMODM1
	RET			;IF NOT, RETURN

CKMODM1:
	CALL	INMODDATP	;OTHERWISE GET THE CHARACTER AND IGNORE
	JMP	CKMODM		;CHECK FOR ANY ADDITIONAL CHARACTERS
;
